﻿import pygame
import sys
import random
import time
from pygame.locals import *

# 初始化 Pygame
pygame.init()

# 游戏常量
WINDOW_WIDTH = 800
WINDOW_HEIGHT = 600
GRID_SIZE = 60
GRID_COLS = 8
GRID_ROWS = 8
MARGIN = 50
FPS = 60

# 颜色定义
BACKGROUND = (40, 44, 52)
GRID_BG = (30, 34, 42)
GRID_BORDER = (50, 54, 62)
TEXT_COLOR = (220, 220, 220)
HIGHLIGHT = (255, 255, 255, 100)

# 拼音字母表 - 声母和韵母
PINYIN_CONSONANTS = ['b', 'p', 'm', 'f', 'd', 't', 'n', 'l', 'g', 'k', 'h', 'j', 'q', 'x', 
                    'zh', 'ch', 'sh', 'r', 'z', 'c', 's', 'y', 'w']
PINYIN_VOWELS = ['a', 'o', 'e', 'i', 'u', 'ü', 'ai', 'ei', 'ui', 'ao', 'ou', 'iu', 'ie', 'üe', 'er',
                'an', 'en', 'in', 'un', 'ün', 'ang', 'eng', 'ing', 'ong']

# 创建游戏窗口
screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption('拼音字母表消消乐')
clock = pygame.time.Clock()

# 加载字体
try:
    font_large = pygame.font.Font('simhei.ttf', 48)
    font_medium = pygame.font.Font('simhei.ttf', 36)
    font_small = pygame.font.Font('simhei.ttf', 24)
except:
    font_large = pygame.font.SysFont(None, 48)
    font_medium = pygame.font.SysFont(None, 36)
    font_small = pygame.font.SysFont(None, 24)

# 创建拼音字母颜色映射
def create_pinyin_colors():
    colors = {}
    color_palette = [
        (255, 107, 107),  # 红色
        (255, 206, 106),  # 橙色
        (255, 250, 105),  # 黄色
        (29, 209, 161),   # 绿色
        (84, 160, 255),   # 蓝色
        (95, 39, 205),    # 紫色
        (200, 107, 255),  # 粉色
        (72, 219, 251),   # 青色
    ]
    
    all_pinyin = PINYIN_CONSONANTS + PINYIN_VOWELS
    for i, pinyin in enumerate(all_pinyin):
        colors[pinyin] = color_palette[i % len(color_palette)]
    
    return colors

PINYIN_COLORS = create_pinyin_colors()

class PinyinTile:
    def __init__(self, pinyin, row, col):
        self.pinyin = pinyin
        self.row = row
        self.col = col
        self.color = PINYIN_COLORS.get(pinyin, (200, 200, 200))
        self.selected = False
        self.matched = False
        self.falling = False
        self.target_row = row
        self.animation_progress = 0
    
    def draw(self, surface):
        # 计算位置
        x = MARGIN + self.col * GRID_SIZE
        y = MARGIN + self.row * GRID_SIZE
        
        # 如果正在下落，计算动画位置
        if self.falling:
            progress = min(1.0, self.animation_progress / 10.0)
            y = MARGIN + (self.target_row * progress + self.row * (1 - progress)) * GRID_SIZE
        
        # 绘制方块背景
        rect = pygame.Rect(x, y, GRID_SIZE, GRID_SIZE)
        pygame.draw.rect(surface, self.color, rect, border_radius=8)
        pygame.draw.rect(surface, GRID_BORDER, rect, 2, border_radius=8)
        
        # 如果被选中，绘制高亮效果
        if self.selected:
            highlight = pygame.Surface((GRID_SIZE, GRID_SIZE), pygame.SRCALPHA)
            pygame.draw.rect(highlight, HIGHLIGHT, (0, 0, GRID_SIZE, GRID_SIZE), border_radius=8)
            surface.blit(highlight, (x, y))
        
        # 绘制拼音文本
        text = font_medium.render(self.pinyin, True, TEXT_COLOR)
        text_rect = text.get_rect(center=(x + GRID_SIZE // 2, y + GRID_SIZE // 2))
        surface.blit(text, text_rect)
    
    def update(self):
        if self.falling:
            self.animation_progress += 1
            if self.animation_progress >= 10:
                self.falling = False
                self.row = self.target_row
                self.animation_progress = 0

class PinyinGame:
    def __init__(self):
        self.grid = []
        self.selected_tiles = []
        self.score = 0
        self.time_left = 120  # 2分钟游戏时间
        self.game_over = False
        self.init_grid()
    
    def init_grid(self):
        # 创建初始网格
        self.grid = [[None for _ in range(GRID_COLS)] for _ in range(GRID_ROWS)]
        
        # 填充网格
        all_pinyin = PINYIN_CONSONANTS + PINYIN_VOWELS
        for row in range(GRID_ROWS):
            for col in range(GRID_COLS):
                pinyin = random.choice(all_pinyin)
                self.grid[row][col] = PinyinTile(pinyin, row, col)
    
    def draw(self, surface):
        # 绘制背景
        surface.fill(BACKGROUND)
        
        # 绘制网格背景
        grid_rect = pygame.Rect(
            MARGIN - 10, MARGIN - 10,
            GRID_COLS * GRID_SIZE + 20, GRID_ROWS * GRID_SIZE + 20
        )
        pygame.draw.rect(surface, GRID_BG, grid_rect, border_radius=12)
        pygame.draw.rect(surface, GRID_BORDER, grid_rect, 2, border_radius=12)
        
        # 绘制所有方块
        for row in range(GRID_ROWS):
            for col in range(GRID_COLS):
                if self.grid[row][col]:
                    self.grid[row][col].draw(surface)
        
        # 绘制分数和时间
        score_text = font_medium.render(f"分数: {self.score}", True, TEXT_COLOR)
        surface.blit(score_text, (20, 20))
        
        time_text = font_medium.render(f"时间: {int(self.time_left)}秒", True, TEXT_COLOR)
        surface.blit(time_text, (WINDOW_WIDTH - 150, 20))
        
        # 如果游戏结束，显示游戏结束画面
        if self.game_over:
            self.draw_game_over(surface)
    
    def draw_game_over(self, surface):
        # 创建半透明覆盖层
        overlay = pygame.Surface((WINDOW_WIDTH, WINDOW_HEIGHT), pygame.SRCALPHA)
        overlay.fill((0, 0, 0, 180))
        surface.blit(overlay, (0, 0))
        
        # 显示游戏结束文本
        game_over_text = font_large.render("游戏结束!", True, TEXT_COLOR)
        game_over_rect = game_over_text.get_rect(center=(WINDOW_WIDTH // 2, WINDOW_HEIGHT // 2 - 50))
        surface.blit(game_over_text, game_over_rect)
        
        score_text = font_medium.render(f"最终分数: {self.score}", True, TEXT_COLOR)
        score_rect = score_text.get_rect(center=(WINDOW_WIDTH // 2, WINDOW_HEIGHT // 2))
        surface.blit(score_text, score_rect)
        
        restart_text = font_medium.render("按R键重新开始", True, TEXT_COLOR)
        restart_rect = restart_text.get_rect(center=(WINDOW_WIDTH // 2, WINDOW_HEIGHT // 2 + 50))
        surface.blit(restart_text, restart_rect)
    
    def update(self, dt):
        # 更新游戏时间
        if not self.game_over:
            self.time_left -= dt
            if self.time_left <= 0:
                self.time_left = 0
                self.game_over = True
        
        # 更新所有方块
        for row in range(GRID_ROWS):
            for col in range(GRID_COLS):
                if self.grid[row][col]:
                    self.grid[row][col].update()
    
    def handle_click(self, pos):
        if self.game_over:
            return
        
        # 将屏幕坐标转换为网格坐标
        col = (pos[0] - MARGIN) // GRID_SIZE
        row = (pos[1] - MARGIN) // GRID_SIZE
        
        # 检查是否在网格范围内
        if 0 <= row < GRID_ROWS and 0 <= col < GRID_COLS and self.grid[row][col]:
            tile = self.grid[row][col]
            
            # 如果已经选中，取消选中
            if tile in self.selected_tiles:
                tile.selected = False
                self.selected_tiles.remove(tile)
            else:
                # 选中新方块
                tile.selected = True
                self.selected_tiles.append(tile)
                
                # 如果选中了三个相同拼音的方块，进行消除
                if len(self.selected_tiles) == 3:
                    if self.check_match():
                        self.remove_matched_tiles()
                        self.score += 30
                    else:
                        # 如果不匹配，取消选中所有方块
                        for t in self.selected_tiles:
                            t.selected = False
                        self.selected_tiles = []
    
    def check_match(self):
        # 检查选中的三个方块是否具有相同的拼音
        if len(self.selected_tiles) != 3:
            return False
        
        pinyin = self.selected_tiles[0].pinyin
        for tile in self.selected_tiles[1:]:
            if tile.pinyin != pinyin:
                return False
        
        return True
    
    def remove_matched_tiles(self):
        # 移除匹配的方块
        for tile in self.selected_tiles:
            self.grid[tile.row][tile.col] = None
        
        # 应用重力效果，让上方的方块下落
        self.apply_gravity()
        
        # 填充空缺的位置
        self.fill_empty_spaces()
        
        # 清空选中列表
        self.selected_tiles = []
    
    def apply_gravity(self):
        # 从底部向上检查每一列
        for col in range(GRID_COLS):
            # 计算每列中的空位
            empty_rows = []
            for row in range(GRID_ROWS - 1, -1, -1):
                if self.grid[row][col] is None:
                    empty_rows.append(row)
            
            # 将上方的方块下落到空位
            for empty_row in empty_rows:
                # 找到空位上方的第一个非空方块
                source_row = empty_row - 1
                while source_row >= 0 and self.grid[source_row][col] is None:
                    source_row -= 1
                
                if source_row >= 0:
                    # 移动方块
                    tile = self.grid[source_row][col]
                    self.grid[source_row][col] = None
                    tile.target_row = empty_row
                    tile.falling = True
                    self.grid[empty_row][col] = tile
    
    def fill_empty_spaces(self):
        # 创建新的拼音字母填充空缺
        all_pinyin = PINYIN_CONSONANTS + PINYIN_VOWELS
        
        for col in range(GRID_COLS):
            for row in range(GRID_ROWS):
                if self.grid[row][col] is None:
                    pinyin = random.choice(all_pinyin)
                    new_tile = PinyinTile(pinyin, row, col)
                    new_tile.falling = True
                    new_tile.animation_progress = 0
                    self.grid[row][col] = new_tile
    
    def restart(self):
        self.__init__()

# 显示开始界面
def show_start_screen():
    screen.fill(BACKGROUND)
    
    # 显示游戏标题
    title_text = font_large.render("拼音字母表消消乐", True, TEXT_COLOR)
    title_rect = title_text.get_rect(center=(WINDOW_WIDTH // 2, WINDOW_HEIGHT // 2 - 50))
    screen.blit(title_text, title_rect)
    
    # 显示游戏说明
    instruction_text = font_medium.render("点击三个相同拼音的字母进行消除", True, TEXT_COLOR)
    instruction_rect = instruction_text.get_rect(center=(WINDOW_WIDTH // 2, WINDOW_HEIGHT // 2))
    screen.blit(instruction_text, instruction_rect)
    
    # 显示开始提示
    start_text = font_medium.render("点击任意位置开始游戏", True, TEXT_COLOR)
    start_rect = start_text.get_rect(center=(WINDOW_WIDTH // 2, WINDOW_HEIGHT // 2 + 50))
    screen.blit(start_text, start_rect)
    
    # 显示拼音字母表示例
    y_offset = WINDOW_HEIGHT // 2 + 100
    cons_text = font_small.render("声母: " + " ".join(PINYIN_CONSONANTS[:12]), True, TEXT_COLOR)
    screen.blit(cons_text, (WINDOW_WIDTH // 2 - cons_text.get_width() // 2, y_offset))
    
    cons_text2 = font_small.render("声母: " + " ".join(PINYIN_CONSONANTS[12:]), True, TEXT_COLOR)
    screen.blit(cons_text2, (WINDOW_WIDTH // 2 - cons_text2.get_width() // 2, y_offset + 30))
    
    vowel_text = font_small.render("韵母: " + " ".join(PINYIN_VOWELS[:12]), True, TEXT_COLOR)
    screen.blit(vowel_text, (WINDOW_WIDTH // 2 - vowel_text.get_width() // 2, y_offset + 60))
    
    vowel_text2 = font_small.render("韵母: " + " ".join(PINYIN_VOWELS[12:]), True, TEXT_COLOR)
    screen.blit(vowel_text2, (WINDOW_WIDTH // 2 - vowel_text2.get_width() // 2, y_offset + 90))
    
    pygame.display.flip()
    
    # 等待用户点击
    waiting = True
    while waiting:
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            if event.type == MOUSEBUTTONDOWN:
                waiting = False

# 主游戏循环
def main():
    # 显示开始界面
    show_start_screen()
    
    # 创建游戏实例
    game = PinyinGame()
    
    # 游戏主循环
    last_time = time.time()
    running = True
    while running:
        # 计算时间增量
        current_time = time.time()
        dt = current_time - last_time
        last_time = current_time
        
        # 处理事件
        for event in pygame.event.get():
            if event.type == QUIT:
                running = False
            elif event.type == MOUSEBUTTONDOWN:
                if event.button == 1:  # 左键点击
                    game.handle_click(event.pos)
            elif event.type == KEYDOWN:
                if event.key == K_r:  # 按R键重新开始
                    game.restart()
        
        # 更新游戏状态
        game.update(dt)
        
        # 绘制游戏
        game.draw(screen)
        pygame.display.flip()
        
        # 控制帧率
        clock.tick(FPS)
    
    pygame.quit()
    sys.exit()

if __name__ == "__main__":
    main()